home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / lib / stdio / fopen.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  3KB  |  153 lines

  1.  
  2. /*
  3.  *  FOPEN.C        fopen freopen fdopen
  4.  *
  5.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  6.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  7.  *    DICE-LICENSE.TXT.
  8.  *
  9.  *  modes:    a[b][+]     append [binary] [+ignored]
  10.  *        r[b][+]     read [binary] [update-allow writes]
  11.  *        w[b][+]     write [binary] [uupdate-allow reads]
  12.  *
  13.  *        a always appends- write only
  14.  *        r file must exist '+' means can write too.
  15.  *        w file always create/truncate
  16.  *        b binary (ignored)
  17.  *
  18.  *        F INTERNAL, user should never specify.    Used by fdopen.
  19.  */
  20.  
  21. #include <clib/dos_protos.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <fcntl.h>
  25. #include <errno.h>
  26. #include <string.h>
  27. #include <lib/misc.h>
  28.  
  29. FILE *
  30. fopen(name, modes)
  31. const char *name;
  32. const char *modes;
  33. {
  34.     FILE *fi = malloc(sizeof(FILE));
  35.  
  36.     if (fi) {
  37.     _slow_bzero(fi, sizeof(FILE));
  38.     if (freopen(name, modes, fi) == NULL) {
  39.         free(fi);
  40.         fi = NULL;
  41.     }
  42.     }
  43.     return(fi);
  44. }
  45.  
  46. FILE *
  47. fdopen(fd, modes)
  48. int fd;
  49. const char *modes;
  50. {
  51.     char buf[16];
  52.  
  53.     if (strlen(modes) < 14) {
  54.     buf[0] = 'F';
  55.     strcpy(buf + 1, modes);
  56.     return(fopen((char *)fd, buf));
  57.     }
  58.     return(NULL);
  59. }
  60.  
  61. FILE *
  62. freopen(name, modes, fi)
  63. const char *name;
  64. const char *modes;
  65. FILE *fi;
  66. {
  67.     short fdmode = 0;
  68.     short fimode = 0;
  69.     short fdOpen = 0;
  70.  
  71.     if (fi == stdin || fi == stdout || fi == stderr)
  72.     fimode |= __SIF_NOFREE;
  73.  
  74.     {
  75.     char c;
  76.     while (c = *modes) {
  77.         if (c == 'r') {
  78.         fdmode |= O_RDONLY;
  79.         fimode |= __SIF_READ;
  80.         }
  81.         if (c == 'w') {
  82.         fdmode |= O_WRONLY | O_CREAT | O_TRUNC;
  83.         fimode |= __SIF_WRITE;
  84.         }
  85.         if (c == '+') {
  86.         fdmode |= O_RDWR;
  87.         fdmode &= ~(O_RDONLY|O_WRONLY);
  88.         fimode |= __SIF_READ | __SIF_WRITE;
  89.         }
  90.         if (c == 'b') {
  91.         fdmode |= O_BINARY;
  92.         fimode |= __SIF_BINARY;
  93.         }
  94.         if (c == 'a') {
  95.         fdmode |= O_CREAT | O_APPEND;
  96.         fimode |= __SIF_WRITE | __SIF_APPEND;
  97.         }
  98.         if (c == 'F')       /*  INTERNAL    */
  99.         fdOpen = 1;
  100.         if (c == 'C')       /*  INTERNAL    */
  101.         fimode |= __SIF_REMOVE;
  102.         ++modes;
  103.     }
  104.     }
  105.     if (fi) {
  106.     if (fi->sd_Flags & __SIF_OPEN) {
  107.         __fclose(fi);
  108.         if ( (fimode & __SIF_REMOVE) && (fi->sd_Name))free(fi->sd_Name);
  109.         // disconnect file handle
  110.         if ((fi->sd_Flags & __SIF_NOFREE) == 0) {
  111.             *fi->sd_Prev = fi->sd_Next;
  112.             if (fi->sd_Next)fi->sd_Next->sd_Prev = fi->sd_Prev;
  113.         }
  114.     }
  115.     _slow_bzero(fi, sizeof(FILE));
  116.     if (fdOpen)
  117.         fi->sd_Fd = (int)name;
  118.     else
  119.         fi->sd_Fd = open(name, fdmode, 0666);
  120.  
  121.     if (fi->sd_Fd >= 0) {
  122.         fi->sd_UC = -1;
  123.  
  124.         if ((fimode & __SIF_NOFREE) == 0) {
  125.         fi->sd_Next = _Iod;
  126.         fi->sd_Prev = &_Iod;
  127.         if (fi->sd_Next)
  128.             fi->sd_Next->sd_Prev = &fi->sd_Next;
  129.         _Iod = fi;
  130.         }
  131.         {
  132.         long pos = lseek(fi->sd_Fd, 0, 1);
  133.  
  134.         if (pos >= 0) {
  135.             fimode |= __SIF_FILE;
  136.             fi->sd_Offset = pos;
  137.         }
  138.         }
  139.  
  140.         fi->sd_BufSiz = _bufsiz;
  141.         fi->sd_Flags = __SIF_OPEN | fimode;
  142.         fi->sd_RLeft = -1;
  143.         fi->sd_WLeft = -1;
  144.         if (fimode & __SIF_REMOVE)
  145.         fi->sd_Name = name;    /*  name assumed to be malloc'd */
  146.     } else {
  147.         return(NULL);
  148.     }
  149.     }
  150.     return(fi);
  151. }
  152.  
  153.